import { Injectable } from '@nestjs/common';
import { PaginationDto } from './dto/pagination.dto';
import { CursorPaginationDto } from './dto/cursorPagination.dto';
import { Repository, FindManyOptions, LessThan, MoreThan } from 'typeorm';

@Injectable()
export class PaginationService {
  async pagination<T>(
    repository: Repository<T>,
    paginationDto: PaginationDto,
    options: FindManyOptions,
  ) {
    const {
      curPage = 1,
      pageSize = 10,
      sortBy,
      sortOrder = 'DESC',
    } = paginationDto;

    // 构造查找参数
    const findOptions: FindManyOptions = {
      skip: (curPage - 1) * pageSize,
      take: pageSize,
      ...options,
    };

    if (sortBy) {
      findOptions.order = { [sortBy]: sortOrder };
    }
    console.log(paginationDto, pageSize, typeof pageSize);

    // 查询数据
    const [list, total] = await repository.findAndCount(findOptions);

    return {
      list,
      pagination: {
        total,
        pageSize,
        curPage,
        totalPage: Math.ceil(total / pageSize),
        isEnd: curPage >= Math.ceil(total / pageSize),
      },
    };
  }

  // 1. 按时间倒序数据
  // 2. 根据游标id，查找小于该ID的数据
  // 3. 根据pagesize，取出数据条数
  async cursorPagination<T>(
    repository: Repository<T>,
    paginationDto: CursorPaginationDto,
    options: FindManyOptions<T>,
  ) {
    const {
      sortOrder = 'DESC',
      pageSize = 10,
      cursorField = 'createdAt',
      cursor,
    } = paginationDto;

    console.log('paginationDto', sortOrder, pageSize, cursorField, cursor);

    let where: any = options.where || {};
    if (cursor) {
      if (sortOrder === 'DESC') {
        where[cursorField] = LessThan(cursor);
      } else {
        where[cursorField] = MoreThan(cursor);
      }
    }

    const findOptions: FindManyOptions = {
      ...options,
      where,
      take: pageSize, // 取pageSize条数据
      order: { [cursorField]: sortOrder } as FindManyOptions<T>['order'], // 按指定字段排序
    };

    // 查询数据
    const list = await repository.find(findOptions);

    // 新的游标：如果list有数据，则取list的最后一个元素的cursorField值，否则为null
    const nextCursor =
      list.length > 0 ? (list[list.length - 1] as any)[cursorField] : null;

    return {
      list,
      pagination: {
        pageSize,
        nextCursor,
        isEnd: list.length < pageSize,
      },
    };
  }
}
